﻿using System.Threading;
using System.Windows.Forms;
using Loki.Utils;

namespace Loki.UI.Win
{
    public class WinFormBootStrapper<TMainViewModelType> : ApplicationContext, IPlatform
        where TMainViewModelType : class, IScreen
    {
        private object mainObject;
        private WinformSignalManager signals = new WinformSignalManager();
        private WinformTemplatingEngine templates;
        private WinformThreadingContext threading = new WinformThreadingContext();
        private WinformWindowManager windows = new WinformWindowManager();

        public WinFormBootStrapper()
        {
            if (!windows.DesignMode)
            {
                templates = new WinformTemplatingEngine();
                BootStrapper = new BootStrapperAdapter<TMainViewModelType>(this);
            }
        }

        public object MainObject
        {
            get
            {
                return mainObject;
            }

            set
            {
                MainForm = Templates.GetTemplate(value) as Form;
                mainObject = value;
            }
        }

        public ISignalManager Signals
        {
            get { return signals; }
        }

        public virtual ITemplatingEngine Templates
        {
            get { return templates; }
        }

        public IThreadingContext Threading
        {
            get { return threading; }
        }

        public IWindowManager Windows
        {
            get { return windows; }
        }

        protected BootStrapperAdapter<TMainViewModelType> BootStrapper { get; private set; }

        #region Log

        private ILog _Log = null;

        /// <summary>
        /// Gets the logger.
        /// </summary>
        /// <value>The logger.</value>
        protected ILog Log
        {
            get
            {
                if (_Log == null)
                {
                    Interlocked.CompareExchange(ref _Log, Toolkit.Logger.GetLog(this.GetType().Name), null);
                }

                return _Log;
            }
        }

        #endregion Log

        public void Run(string[] args)
        {
            Application.SetCompatibleTextRenderingDefault(false);

            // If using EnableVisualStyles, always call DoEvents immediately afterwards. Failing to
            // do so can result in an unexpected SEHException.
            Application.EnableVisualStyles();
            Application.DoEvents();

            signals.OnApplicationStart(new StartupEventArgs() { Parameters = args });

            Application.Run(this);
        }
    }
}